package medOffice;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import medOffice.Enuns.Sexo;

/**
 * Classe que manipula os arquivos de configuração do MedOffice
 * 
 * @author Ana Clara Lacerda - anacls@lcc.ufcg.edu.br
 * @version 0.1 - 01/12/2009
 */
public class Configuracoes {

	/**
	 * Salva os dados da Clinica e do Medico
	 * 
	 * @param List<String> listaClinica
	 *            lista da dados da clinica
	 * @param List<String> listaMedico
	 *            lista de dados do medico
	 */
	public static void salvaDados(List<String> listaClinica,
			List<String> listaMedico) {
		try {
			salvaClinica(listaClinica);
			salvaMedico(listaMedico);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Salva o medico no arquivo "conf_medico.txt"
	 * 
	 * @param List<String> lista
	 *            lista de dados do medico
	 * @throws IOException
	 */
	public static void salvaMedico(List<String> lista) throws IOException {
		ObjectOutputStream out = null;
		String nomeDoArquivo = "conf_medico.txt";
		try {
			out = new ObjectOutputStream(new FileOutputStream(nomeDoArquivo));
			for (String str : lista) {
				out.writeObject(str);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null)
				out.close();
		}
	}

	/**
	 * Salva a Clinica no arquivo "conf_clinica.txt"
	 * 
	 * @param List<String>
	 *            lista de dados da clinica
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void salvaClinica(List<String> lista)
			throws FileNotFoundException, IOException {
		ObjectOutputStream out = null;
		String nomeDoArquivo = "conf_clinica.txt";
		try {
			out = new ObjectOutputStream(new FileOutputStream(nomeDoArquivo));
			for (String str : lista) {
				out.writeObject(str);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null)
				out.close();
		}

	}

	/**
	 * Salva a lista de horarios em Arquivo.
	 * 
	 * @param Integer dia
	 *            o dia a qual pertencem os horarios
	 * @param List<String> lista
	 *            lista de horarios
	 * @throws IOException
	 */
	public static void salvaHorarios(Integer dia, List<String> lista)
			throws IOException {
		Map<Integer, List<String>> mapa = new HashMap<Integer, List<String>>();
		try {
			mapa = getHorarios();
		} catch (Exception e) {

		}
		mapa.put(dia, lista);
		ObjectOutputStream out = null;
		String nomeDoArquivo = "conf_horarios.txt";
		try {
			out = new ObjectOutputStream(new FileOutputStream(nomeDoArquivo));
			for (Integer i : mapa.keySet()) {
				out.writeObject(i);
				out.writeObject(mapa.get(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null)
				out.close();
		}
	}

	/**
	 * Metodo que abre o arquivo "conf_horarios.txt" e salva os dados ja existentes nele
	 * 
	 * @return Map<Integer, List<String>> um Mapa com os dados do arquivo
	 * @throws IOException
	 */
	public static Map<Integer, List<String>> getHorarios() throws IOException {
		Map<Integer, List<String>> mapa = new HashMap<Integer, List<String>>();
		ObjectInputStream out = null;
		String nomeDoArquivo = "conf_horarios.txt";
		try {
			out = new ObjectInputStream(new FileInputStream(nomeDoArquivo));
			while (true) {
				Integer obj = (Integer) out.readObject();
				List<String> list = (List<String>) out.readObject();
				if (list != null)
					mapa.put(obj, list);				
			}
		} catch (Exception e) {

		} finally {
			if (out != null)
				out.close();
		}
		return mapa;
	}

	/**
	 * Abre o arquivo "conf_horarios.txt" e exibe na tela o seu conteudo
	 * 
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void testaArquivo() throws FileNotFoundException, IOException {
		ObjectInputStream out = null;
		String nomeDoArquivo = "conf_horarios.txt";
		try {
			out = new ObjectInputStream(new FileInputStream(nomeDoArquivo));
			while (true) {
				Integer obj = (Integer) out.readObject();
				List<String> list = (List<String>) out.readObject();
			}
		} catch (Exception e) {

		} finally {
			if (out != null)
				out.close();
		}
	}

	/**
	 * Verifica a existencia de um arquivo
	 * 
	 * @param String
	 *            Nome do arquivo que vai ser verificado
	 * @return boolean 
	 * 				True caso exista, False caso contrario
	 */
	public static boolean verificaExistencia(String nomeDoArquivo) {
		File f = new File(nomeDoArquivo);
		return f.exists();
	}

	/**
	 * Abre o arquivo "conf_clinica.txt" e retorna uma lista com o seu conteudo
	 * 
	 * @return List<String> uma lista com os dados da clinica
	 * @throws IOException
	 */
	public static List<String> getDadosDaClinica() throws IOException {
		ObjectInputStream out = null;
		String nomeDoArquivo = "conf_clinica.txt";
		List<String> dados = new ArrayList<String>();
		try {
			out = new ObjectInputStream(new FileInputStream(nomeDoArquivo));
			while (true) {
				String obj = (String) out.readObject();
				dados.add(obj);
			}
		} catch (Exception e) {

		} finally {
			if (out != null)
				out.close();
		}
		return dados;
	}

	/**
	 * Abre o arquivo "conf_medico.txt" e retorna uma lista com o seu conteudo
	 * 
	 * @return  List<String> uma lista com os dados do Medico
	 * @throws IOException
	 */
	public static List<String> getDadosDoMedico() throws IOException {
		ObjectInputStream out = null;
		String nomeDoArquivo = "conf_medico.txt";
		List<String> dados = new ArrayList<String>();
		try {
			out = new ObjectInputStream(new FileInputStream(nomeDoArquivo));
			while (true) {
				String obj = (String) out.readObject();
				dados.add(obj);
			}
		} catch (Exception e) {

		} finally {
			if (out != null)
				out.close();
		}
		return dados;
	}

	/**
	 * Le os dados do arquivo "conf_medico.txt" e cria o Medico com esses dados
	 * 
	 * @return Medico devidamente criado
	 * @throws Exception
	 *             Caso o arquivo nao exista ou algum dado seja invalido
	 */
	private static Medico capturaMedico() throws Exception {
		if (!verificaExistencia("conf_medico.txt"))
			throw new Exception("Arquivo nao existente");
		List<String> dados = getDadosDoMedico();
		Medico medico = new Medico(dados.get(0), dados.get(1));
		medico.setEndereco(dados.get(2));
		medico.setEmail(dados.get(3));
		medico.setTelefone(dados.get(4));
		medico.setSexo(Sexo.valueOf(dados.get(5)));
		medico.setDataDeNascimento(dados.get(6));
		medico.setTempoConsulta(dados.get(7));
		medico.setTempoRetorno(dados.get(8));
		setHorarios(medico);
		return medico;
	}

	/**
	 * Pega uma lista de String e tranforma em arrays com pares de Times
	 * 
	 * @param List<String>
	 *            a lista de String que vai ser tranformada
	 * @return List<Time[]> uma lista de pares de Time
	 */
	private static List<Time[]> organizaTimes(List<String> lista) {
		List<Time[]> times = new ArrayList<Time[]>();
		for (int i = 0; i < lista.size() - 1; i += 2) {
			if (!lista.get(i).equals("") && !lista.get(i + 1).equals("")) {
				times.add(new Time[] { Time.valueOf(lista.get(i)+":00"),
						Time.valueOf(lista.get(i + 1)+":00") });
			}
		}
		return times;
	}

	/**
	 * Le os horarios do arquivo "conf_horarios.txt" e seta no Medico
	 * 
	 * @param Medico
	 *           medico onde os horarios serao setados
	 * @throws Exception
	 *             Caso o arquivo nao exista ou os horarios sejam invalidos
	 */
	private static void setHorarios(Medico m) throws Exception {
		if (!verificaExistencia("conf_horarios.txt"))
			throw new Exception("Arquivo nao existente");
		Map<Integer, List<Time[]>> mapa = new HashMap<Integer, List<Time[]>>();
		for (Integer i : getHorarios().keySet()) {
			mapa.put(i, organizaTimes(getHorarios().get(i)));
		}
		m.setHorariosDisponiveis(mapa);
	}

	/**
	 * Captura a Clinica de acordo com os dados dos tres arquivos de configuracao
	 * 
	 * @return Clinica criada
	 * @throws Exception
	 *             caso algum arquivo nao exista
	 */
	public static Clinica capturaClinica() throws Exception {
		if (!verificaExistencia("conf_clinica.txt"))
			throw new Exception("Arquivo nao existente");
		List<String> dados = getDadosDaClinica();
		Clinica clinica = new Clinica(dados.get(0));
		clinica.setEndereco(dados.get(1));
		clinica.setTelefone(dados.get(2));
		Agenda agenda = new Agenda(capturaMedico());
		clinica.setAgenda(agenda);
		return clinica;
	}

	/**
	 * Verifica a existencia de todos os tres arquivos de configuracao
	 * 
	 * @return boolean True caso os tres existam, False caso contrario
	 */
	public static boolean existeConfiguracoes() {
		return (verificaExistencia("conf_medico.txt")
				&& verificaExistencia("conf_clinica.txt") && verificaExistencia("conf_horarios.txt"));
	}
	
}
